home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2006 December / PCWDEC06.iso / Software / Freeware / Gmail Manager 0.5.1 / gmanager051.xpi / components / gmParser.js < prev    next >
Encoding:
Text File  |  2006-08-28  |  11.3 KB  |  335 lines

  1. // Gmail Manager
  2. // By Todd Long <longfocus@gmail.com>
  3. // http://www.longfocus.com/firefox/gmanager/
  4.  
  5. const GM_CC = Components.classes;
  6. const GM_CI = Components.interfaces;
  7.  
  8. function gmParser() {}
  9. gmParser.prototype = {
  10.   _console: null,
  11.   _manager: null,
  12.   _converter: null,
  13.   _domParser: null,
  14.   _domSerializer: null,
  15.   _xpathEval: null,
  16.   _doc: null,
  17.   
  18.   get doc() {
  19.     if (!this._doc)
  20.       this.load();
  21.     return this._doc.documentElement;
  22.   },
  23.   
  24.   get account() {
  25.     if (!this._domParser)
  26.       this.load();
  27.     return this._domParser.parseFromString(
  28.              '  <account type="" email="" alias="">\n' +
  29.              '    <pref id="general-automatic-login" type="Bool" value="false"/>\n' +
  30.              '    <pref id="general-secured-connection" type="Bool" value="true"/>\n' +
  31.              '    <pref id="toolbar-account-hide-unread-count" type="Bool" value="false"/>\n' +
  32.              '    <pref id="toolbar-account-hide-alias" type="Bool" value="false"/>\n' +
  33.              '    <pref id="toolbar-tooltip-show-labels" type="Bool" value="true"/>\n' +
  34.              '    <pref id="toolbar-tooltip-show-snippets" type="Bool" value="true"/>\n' +
  35.              '    <pref id="toolbar-tooltip-show-accounts" type="Bool" value="false"/>\n' +
  36.              '    <pref id="toolbar-unread-count-inbox" type="Bool" value="true"/>\n' +
  37.              '    <pref id="toolbar-unread-count-spam" type="Bool" value="false"/>\n' +
  38.              '    <pref id="toolbar-unread-count-labels" type="Bool" value="false"/>\n' +
  39.              '    <pref id="notifications-check-interval" type="Int" value="15"/>\n' +
  40.              '    <pref id="notifications-alerts-message-count" type="Bool" value="false"/>\n' +
  41.              '    <pref id="notifications-alerts-snippets" type="Bool" value="false"/>\n' +
  42.              '    <pref id="notifications-sounds" type="Bool" value="false"/>\n' +
  43.              '    <pref id="notifications-sounds-file" type="Char" value=""/>\n' +
  44.              '  </account>\n', "text/xml").documentElement;
  45.   },
  46.   
  47.   load: function()
  48.   {
  49.     // Load services
  50.     this._console = GM_CC['@mozilla.org/consoleservice;1'].getService(GM_CI.nsIConsoleService);
  51.     this._manager = GM_CC["@longfocus.com/gmanager/manager;1"].getService(GM_CI.gmIManager);
  52.     this._converter = GM_CC["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(GM_CI.nsIScriptableUnicodeConverter);
  53.     this._domParser = GM_CC['@mozilla.org/xmlextras/domparser;1'].getService(GM_CI.nsIDOMParser);
  54.     this._domSerializer = GM_CC['@mozilla.org/xmlextras/xmlserializer;1'].getService(GM_CI.nsIDOMSerializer);
  55.     this._xpathEval = GM_CC["@mozilla.org/dom/xpath-evaluator;1"].createInstance(GM_CI.nsIDOMXPathEvaluator);
  56.     
  57.     // Initialize converter
  58.     this._converter.charset = "UTF-8";
  59.     
  60.     // Load preferences
  61.     if (this._getPrefsFile("prefs.xml").exists())
  62.       this.open(this._getPrefsFile("prefs.xml"));
  63.     
  64.     if (this._doc == null && this._getPrefsFile("prefs.bak").exists())
  65.       this.open(this._getPrefsFile("prefs.bak"));
  66.     
  67.     if (this._doc == null)
  68.       this._doc = this._defaultXML();
  69.   },
  70.   
  71.   open: function(aFile)
  72.   {
  73.     var doc = this._readXML(aFile);
  74.     
  75.     if (doc != null)
  76.     {
  77.       // Transform prefs
  78.       doc = this._transform(doc);
  79.       
  80.       // Validate prefs
  81.       if (this._validate(doc))
  82.         this._doc = doc;
  83.       else
  84.         doc = null;
  85.     }
  86.     
  87.     return (doc != null);
  88.   },
  89.   
  90.   save: function(aFile)
  91.   {
  92.     var file = (aFile != null ? aFile : this._getPrefsFile("prefs.xml"));
  93.     
  94.     // Backup prefs file
  95.     if (aFile == null && this._getPrefsFile("prefs.xml").exists())
  96.       this._getPrefsFile("prefs.xml").moveTo(null, "prefs.bak");
  97.     
  98.     this._writeXML(file, this._doc);
  99.   },
  100.   
  101.   _readXML: function(aFile)
  102.   {
  103.     var doc = null;
  104.     var fiStream = null;
  105.     var siStream = null;
  106.     
  107.     try {
  108.       var data = new String();
  109.       
  110.       fiStream = GM_CC["@mozilla.org/network/file-input-stream;1"].createInstance(GM_CI.nsIFileInputStream);
  111.       siStream = GM_CC["@mozilla.org/scriptableinputstream;1"].createInstance(GM_CI.nsIScriptableInputStream);
  112.       
  113.       fiStream.init(aFile, 1, 0, false);
  114.       siStream.init(fiStream);
  115.       
  116.       while (siStream.available() > 0)
  117.       {
  118.         var chunk = siStream.read(siStream.available());
  119.         data += this._converter.ConvertToUnicode(chunk);      
  120.       }
  121.       
  122.       doc = this._domParser.parseFromString(data, "text/xml");
  123.     }
  124.     catch(e) {}
  125.     finally {
  126.       if (fiStream != null)
  127.         fiStream.close();
  128.       if (siStream != null)
  129.         siStream.close();
  130.     }
  131.     
  132.     return doc;
  133.   },
  134.   
  135.   _writeXML: function(aFile, aDoc)
  136.   {
  137.     var content = this._domSerializer.serializeToString(aDoc);
  138.     var foStream = null;
  139.     
  140.     try {
  141.       // Create file out stream instance
  142.       foStream = GM_CC["@mozilla.org/network/file-output-stream;1"].createInstance(GM_CI.nsIFileOutputStream);
  143.       
  144.       // Initialize file out stream to write
  145.       foStream.init(aFile, 0x02 | 0x08 | 0x20, 0664, 0);
  146.       
  147.       // Write content to file
  148.       var chunk = this._converter.ConvertFromUnicode(content);
  149.       foStream.write(chunk, chunk.length);
  150.       
  151.       // Check if any content is left
  152.       var fin = this._converter.Finish();
  153.       if (fin.length > 0)
  154.         foStream.write(fin, fin.length);
  155.     }
  156.     catch(e) {}
  157.     finally {
  158.       if (foStream != null)
  159.         foStream.close();
  160.     }
  161.   },
  162.   
  163.   _defaultXML: function()
  164.   {
  165.     return this._domParser.parseFromString(
  166.              '<?xml version="1.0"?>\n' + 
  167.              '<prefs version="' + this._manager.version + '">\n' +
  168.              this._domSerializer.serializeToString(this._defaultGlobalXML()) +
  169.              '</prefs>', "text/xml");
  170.   },
  171.   
  172.   _defaultGlobalXML: function()
  173.   {
  174.     return this._domParser.parseFromString(
  175.              '  <account type="global">\n' +
  176.              '    <pref id="general-never-save-passwords" type="Bool" value="false"/>\n' +
  177.              '    <pref id="compose-tab-location" type="List" value="2"/>\n' +
  178.              '    <pref id="compose-mailto-links" type="Bool" value="false"/>\n' +
  179.              '    <pref id="compose-mailto-default" type="List" value="0"/>\n' +
  180.              '    <pref id="compose-context-menu" type="Bool" value="false"/>\n' +
  181.              '    <pref id="compose-context-menu-mailto" type="Bool" value="false"/>\n' +
  182.              '    <pref id="compose-context-menu-position" type="Int" value="0"/>\n' +
  183.              '    <pref id="toolbar-left-click" type="List" value="7"/>\n' +
  184.              '    <pref id="toolbar-middle-click" type="List" value="2"/>\n' +
  185.              '    <pref id="toolbar-reset-unread-count" type="Bool" value="false"/>\n' +
  186.              '    <pref id="toolbar-statusbar-display" type="Bool" value="true"/>\n' +
  187.              '    <pref id="toolbar-statusbar-always-last" type="List" value="0"/>\n' +
  188.              '    <pref id="toolbar-statusbar-position" type="Int" value="0"/>\n' +
  189.              '    <pref id="notifications-switch-account" type="Bool" value="false"/>\n' +
  190.              '    <pref id="notifications-clickable-alerts" type="Bool" value="true"/>\n' +
  191.              '  </account>\n', "text/xml");
  192.   },
  193.   
  194.   _getPrefsFile: function(aFilename)
  195.   {
  196.     var file = GM_CC["@mozilla.org/file/directory_service;1"].getService(GM_CI.nsIProperties).get("ProfD", GM_CI.nsIFile);
  197.     
  198.     // Append prefs directory
  199.     file.append("gmanager");
  200.     
  201.     // Ensure directory
  202.     if (!file.exists())
  203.       file.create(file.DIRECTORY_TYPE, 0755);
  204.     
  205.     // Append filename
  206.     file.append(aFilename)
  207.     
  208.     return file;
  209.   },
  210.   
  211.   _transform: function(aDoc)
  212.   {
  213.     var processor = GM_CC["@mozilla.org/document-transformer;1?type=xslt"].createInstance(GM_CI.nsIXSLTProcessor);
  214.     var transforms = GM_CC["@mozilla.org/file/directory_service;1"].getService(GM_CI.nsIProperties).get("ProfD", GM_CI.nsIFile);
  215.     var oldVersion = aDoc.documentElement.getAttribute("version");
  216.     var newVersion = this._manager.version;
  217.     var doc = aDoc;
  218.     
  219.     if (oldVersion == null)
  220.       oldVersion = "0.5";
  221.     
  222.     // Transforms directory
  223.     //transforms.append("gmanager");
  224.     transforms.append("extensions");
  225.     transforms.append("{582195F5-92E7-40a0-A127-DB71295901D7}");
  226.     transforms.append("defaults");
  227.     transforms.append("transforms");
  228.     
  229.     while (oldVersion != newVersion && doc != null)
  230.     {
  231.       // Transform file
  232.       var sheet = transforms.clone();
  233.       sheet.append("prefs-" + oldVersion + ".xsl");
  234.       
  235.       try {
  236.         // Process transform
  237.         processor.reset();
  238.         processor.importStylesheet(this._readXML(sheet));
  239.         doc = processor.transformToDocument(doc);
  240.         
  241.         // Version of transform
  242.         oldVersion = doc.documentElement.getAttribute("version");
  243.       } catch(e) {
  244.         // Something went wrong
  245.         doc = null;
  246.       }
  247.     }
  248.     
  249.     return doc;
  250.   },
  251.   
  252.   _validate: function(aDoc)
  253.   {
  254.     var defGlobal = this._defaultGlobalXML();
  255.     var chkGlobal = this._evalPath(aDoc, "//account[@type = 'global']");
  256.     var isValid = (chkGlobal != null);
  257.     
  258.     if (isValid)
  259.     {
  260.       var prefs = defGlobal.getElementsByTagName("pref");
  261.       
  262.       for (var i = 0; i < prefs.length && isValid; i++)
  263.       {
  264.         var id = ("@id='" + prefs.item(i).getAttribute("id") + "'");
  265.         var type = ("@type='" + prefs.item(i).getAttribute("type") + "'");
  266.         var expr = ("pref[" + id + " and " + type + "]");
  267.         isValid = (this._evalPath(chkGlobal, expr) != null);
  268.       }
  269.     }
  270.     
  271.     return isValid;
  272.   },
  273.   
  274.   _evalPath: function(aNode, aExpr)
  275.   {
  276.     var result = null;
  277.     
  278.     try {
  279.       var results = this._xpathEval.evaluate(aExpr, aNode, null, GM_CI.nsIDOMXPathResult.ANY_TYPE, null);
  280.       result = results.iterateNext();
  281.     } catch(e) {}
  282.     
  283.     return result;
  284.   },
  285.   
  286.   QueryInterface: function(iid)
  287.   {
  288.     if (!iid.equals(GM_CI.gmIParser) &&
  289.         !iid.equals(GM_CI.nsISupports))
  290.       throw Components.results.NS_ERROR_NO_INTERFACE;
  291.     return this;
  292.   }
  293. }
  294.  
  295. var myModule = {
  296.   firstTime: true,
  297.   
  298.   myCID: Components.ID("{d0fe9af0-f7bc-11da-974d-0800200c9a66}"),
  299.   myDesc: "Preferences XML parser",
  300.   myProgID: "@longfocus.com/gmanager/parser;1",
  301.   myFactory: {
  302.     createInstance: function (outer, iid) {
  303.       if (outer != null)
  304.         throw Components.results.NS_ERROR_NO_AGGREGATION;
  305.       
  306.       return (new gmParser()).QueryInterface(iid);
  307.     }
  308.   },
  309.   
  310.   registerSelf: function (compMgr, fileSpec, location, type)
  311.   {
  312.     if (this.firstTime) {
  313.       this.firstTime = false;
  314.       throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  315.     }
  316.     
  317.     compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  318.     compMgr.registerFactoryLocation(this.myCID, this.myDesc, this.myProgID, fileSpec, location, type);
  319.   },
  320.  
  321.   getClassObject: function (compMgr, cid, iid)
  322.   {
  323.     if (!cid.equals(this.myCID))
  324.       throw Components.results.NS_ERROR_NO_INTERFACE;
  325.     
  326.     if (!iid.equals(Components.interfaces.nsIFactory))
  327.       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  328.     
  329.     return this.myFactory;
  330.   },
  331.   
  332.   canUnload: function(compMgr) { return true; }
  333. };
  334.  
  335. function NSGetModule(compMgr, fileSpec) { return myModule; }